/*
  jQuery Ui timepickr
  (c) Maxime Haineault <haineault@gmail.com>
  http://haineault.com

  MIT License (http://www.opensource.org/licenses/mit-license.php
Modified under license by Daniel Wachsstock
Modified by Mark Hepburn to use dates rather than times (I don't need a year selection)
*/

(function($) {
	$('<style>'+
		'.ui-datepickr {position:absolute; text-align: left; } '+
		'.ui-datepickr ol { margin-top:2px; } '+
		'.ui-datepickr li {float: left; font-size:.7em; padding:4px 6px 4px 6px; margin-left:2px; cursor: pointer;} '+
		'</style>').appendTo('head');

	var menuTemplate = '<div class="ui-helper-reset ui-datepickr ui-widget" />';
	var rowTemplate = '<ol />';
	var buttonTemplate = '<li class="{className}">{label}</li>';
	function format(s, o){ // simple parameterizing strings
		for (key in o) s = s.replace('{'+key+'}', o[key]);
		return s;
	}

   $.widget('ui.datepickr', {
	 _init: function() {
		var ui = this, element = this.element;
        // Store the initial value so we can restore it if we click outside the menu when resetOnBlur is true:
		element.data('datepickr.initialValue', element.val());
        // Similar; we want to generate a change event on blur only
        // when the new value is the different; we can't use
        // datepickr.initialValue here because that has already been
        // changed by the time blur is called:
		element.data('datepickr.afterBlur', element.val());
		var menu = this.menu = ui._buildMenu().insertAfter(element);
		menu.children().hide();

		element.bind(this.options.trigger + '.datepickr', function(){
			ui.show();
		});

		var hover = this.options.hoverIntent && $.fn.hoverIntent ? 'hoverIntent' : 'hover';
		menu
			.data('datepickr', this)
			.css({width:this.options.width})
			.find('li')
				.addClass('ui-state-default ui-corner-all')
				[hover](function(){
					ui.inside = true;
					$(this).siblings().removeClass('ui-state-hover');
					$(this).addClass('ui-state-hover');
					ui._redraw();
					ui.showNextLevel(this);
					ui.update();
				}, function(){
					ui.inside = false;
				}).end()
			.find('ol')
				.addClass('ui-widget ui-helper-clearfix ui-helper-reset')
				.hide();

		this._redraw();

		element.blur(function(e) {
			ui.hide();
			if (ui.inside){
				// clicking outside the element blurs it before the click on the new element in called
				ui._trigger ('select', [e, ui]);
			}
			if (ui.options.resetOnBlur) {
				element.val(element.data('datepickr.initialValue'));
			}
            if (element.val() != element.data('datepickr.afterBlur')) {
              element.trigger('change');
              element.data('datepickr.afterBlur', element.val());
            }
		});

		if (this.options.val) {
			element.val(this.options.val);
		}

		if (this.options.handle) {
			$(this.options.handle).click(function() {
				ui.show();
				ui.element.focus();
			});
		}

		if (this.options.resetOnBlur) {
			menu.find('li').bind('mousedown.datepickr', function(){
				element.data('datepickr.initialValue', element.val());
			});
		}

		this._redraw();
	},

	update: function() {
      var toDisplayNum = function(num) {
        return num < 10 ? ('0' + num) : ('' + num);
      };
	  var val = {
		mm: toDisplayNum(this.getIndex('month') + 1),
		dd: toDisplayNum(this.getIndex('day') + 1)
	  };
	  $(this.element).val(format(this.options.format, val));
	},

	getIndex: function(type) {
	  // get the 0-based index of the hovered (or first) li item for the requested class:
	  return $('li.' + type, this.menu).index($('.'+ type +'.ui-state-hover', this.menu).add($('.'+type+':first', this.menu))[0]);
	},

	destroy: function() {
		this.menu.remove();
	},

	show: function() {
		this.menu.css({
			top: this.element.position().top + this.element.height() + this.options.top,
			zIndex: 1200
		});
		this.menu.find('ol:eq(0)').css('left', this.element.position().left).show();
	},

	showNextLevel: function(el) {
		$(el).closest('ol').next().show(this.options.animSpeed);
	},

	// essentially reposition each ol
	_redraw: function() {
		this.menu.css({
			top: this.element.position().top + this.element.height() + this.options.top,
			left: this.element.position().left + this.options.left
		});

		// reposition each ol
		var ols = this.menu.find('ol');
		ols.each(function(i) {
			var prevOL = $(this).prev('ol');
			// find the span that's being hovered; if nothing, use the first one (position returns the position of the first item)
            var hovered = prevOL.find('.ui-state-hover:visible').add(prevOL.find('li:visible:first'));
			var pos = hovered.position();
			if (pos) $(this).css('margin-left', pos.left);
            if (prevOL.length === 1) {
              var maxDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
              var idx = prevOL.children().index(hovered[0]);
              $(ols[i]).find('li').hide();
              $(ols[i]).find('li:lt(' + maxDays[idx] + ')').show();
            }
		});
	},

	// hide all levels
	hide: function() {
		this.menu.find('ol').hide();
	},

	activate: function(e) {
		this.element.focus();
		this.show(this.options.animSpeed);
	},

	destroy: function(e) {
		this.menu.remove();
	},

	_createRow: function(range, className) {
		var row = $(rowTemplate);
		$.each(range, function(){
			row.append($(format(buttonTemplate, {className: className, label: this.toString()})));
		});
		return row;
	},

	_getRanges: function() {
		var o = [];
		o.push(this._createRow(this.options.months, 'month'));
		o.push(this._createRow(this.options.days, 'day'));
		return o;
	},

	_buildMenu: function() {
		var menu   = $(menuTemplate);
		var ranges = this._getRanges();
		$.each(ranges, function(i, val){
				menu.append(val);
		});
		return menu;
	}
});

$.ui.datepickr.defaults = {
	top:       6,
	left:      0,
	animSpeed: 0,
	trigger:   'click',
	format:    '{dd}/{mm}',
	handle:      false,
    months: ['J','F','M','A','M','J','J','A','S','O','N','D'],
	days: ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'],
	resetOnBlur: false,
	val:         false,
	hoverIntent: false
};

})(jQuery);
